package org.ayachinene.utils;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.Assert;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;

public class FileRebuilder {

    public static final String PART_FILE_DIR = "/Users/ayachinene/Downloads/.file-splitter";

    public static final String PART_FILE_NAME = "ideaIC-2022.3.1";

    public static final String ORIGIN_FILE_EXTENSION = ".exe";

    public static void main(String[] args) throws IOException {
        Assert.notNull(PART_FILE_DIR, "Part file dir is null!!");
        File dir = new File(PART_FILE_DIR);
        Assert.isTrue(dir.exists() && dir.isDirectory(), "Invalid part file dir!!");
        File[] files = dir.listFiles();
        if (files == null)
            return;

        int maxSeq = 0;
        // Collect part files.
        Map<Integer, File> fileMap = new HashMap<>();
        for (File file : files) {
            String fileName = file.getName();
            if (fileName.startsWith(PART_FILE_NAME)) {
                String s = StringUtils.substringAfter(fileName, "_");
                if (StringUtils.isNumeric(s)) {
                    int i = Integer.parseInt(s);
                    fileMap.put(i, file);
                    maxSeq = Math.max(i, maxSeq);
                }
            }
        }

        File targetFile = FileUtils.getFile(dir, PART_FILE_NAME + ORIGIN_FILE_EXTENSION);
        try (OutputStream out = FileUtils.openOutputStream(targetFile)) {
            // Rebuild
            for (int i = 0; i <= maxSeq; ++i) {
                Assert.isTrue(fileMap.containsKey(i), "Lack of some part files!!");
                File file = fileMap.get(i);
                try (InputStream in = FileUtils.openInputStream(file)) {
                    byte[] bytes = new byte[4 * 1024];
                    int read = in.read(bytes);
                    while (read != -1) {
                        out.write(bytes, 0, read);
                        out.flush();
                        read = in.read(bytes);
                    }
                }
            }
        }
    }
}
